//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <assert.h>
#include <car.h>
#include "marshal.h"

CIBaseType IClassObject_CreateObject_params_[3] = {
    (BT_ATTR_IN | BT_TYPE_INTERFACE), // pOuter
    (BT_ATTR_IN | BT_TYPE_PEMUID), // riid
    (BT_ATTR_OUT | BT_TYPE_PINTERFACE) // ppvObject
};

CIBaseType IClassObject_StayResident_params_[1] = {
    (BT_ATTR_IN | BT_TYPE_UINT32) // fLock
};

CIMethodEntry IClassObject_methods_[2] = {
    { // CreateObject()
        3, // paramNum
        BT_TYPE_UINT32, // result
        0xc3,
        IClassObject_CreateObject_params_
    },
    { // StayResident()
        1, // paramNum
        BT_TYPE_UINT32, // result
        0x01,
        IClassObject_StayResident_params_
    },

};

CIInterfaceEntry ClassObject_interfaceDir_[1] = {
    { // interface IClassObject

        2, // methodNumMinus3
        IClassObject_methods_, // methods
        {0x00000001,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}
    }
};

CIInterfaceEntry * CClassObject_interfaceEntrys_[1] = {
    &(ClassObject_interfaceDir_[0])  // interface IClassObject
};

CIClassEntry ClassObject_classDir_[1] = {
    { // class CClassObject
        {0x0000110A,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x66}},
        "elastos.dll",
        1, // interfaceNum
        CClassObject_interfaceEntrys_
    }
};

CIClassInfo ClassObject_classInfo_ = {
    84,
    1, // classNum
    1, // interfaceNum
    ClassObject_classDir_, // classDir
    ClassObject_interfaceDir_, // interfaceDir
    ""
};

static CIClassInfoNode *s_pServerClassInfoList = NULL;

ECode InitServerClassInfo()
{
    CIClassInfoNode *pNewNode;

    pNewNode = (CIClassInfoNode *)_CMemoryHeap_Alloc(sizeof(CIClassInfoNode), FALSE);
    if (pNewNode == NULL) {
        return E_OUT_OF_MEMORY;
    }

    pNewNode->m_pClsInfo = (CIClassInfo*)&ClassObject_classInfo_;
    pNewNode->m_pNext = NULL;
    s_pServerClassInfoList = pNewNode;

    return NOERROR;
}

ECode RegisterServerClassInfo(
    /* [in] */ const CIClassInfo *pClassInfo)
{
    CIClassInfoNode *pNewNode;

    assert(pClassInfo != NULL);

    pNewNode = (CIClassInfoNode *)_CMemoryHeap_Alloc(sizeof(CIClassInfoNode), FALSE);
    if (pNewNode == NULL) {
        return E_OUT_OF_MEMORY;
    }

    pNewNode->m_pClsInfo = (CIClassInfo *)pClassInfo;
    pNewNode->m_pNext = NULL;
    if (s_pServerClassInfoList == NULL) {
        s_pServerClassInfoList = pNewNode;
    }
    else {
        pNewNode->m_pNext = s_pServerClassInfoList->m_pNext;
        s_pServerClassInfoList->m_pNext = pNewNode;
    }

    return NOERROR;
}

ECode LookupServerClassEntry(
    REMuid rclsid,
    const CIClassEntry **ppClassEntry)
{
    CIClassInfoNode *pCurNode;
    CIClassInfo *pClsInfo;
    int m;

    assert(ppClassEntry != NULL);

    pCurNode = s_pServerClassInfoList;
    while (pCurNode != NULL) {
        pClsInfo = pCurNode->m_pClsInfo;
        for (m = 0; m < pClsInfo->classNum; m++) {
            if (pClsInfo->classDir[m].clsid == rclsid) {
                *ppClassEntry = &(pClsInfo->classDir[m]);
                return NOERROR;
            }
        }
        pCurNode = pCurNode->m_pNext;
    }

    MARSHAL_DBGOUT(MSHDBG_NORMAL, DUMP_GUID(rclsid));

    return E_NO_CLASS_INFO;
}

ECode UnregisterServerClassInfos()
{
    CIClassInfoNode *pCurNode, *pPreNode;

    pCurNode = s_pServerClassInfoList;
    while (pCurNode != NULL) {
        pPreNode = pCurNode;
        pCurNode = pCurNode->m_pNext;
        _CMemoryHeap_Free(pPreNode);
    }

    return NOERROR;
}

